from django.conf import settings as s
import os
import redis
from redis.commands.search.field import TextField, TagField
from redis.commands.search.query import Query
import win32gui
import win32con
import time
import jieba

redis_conn = redis.Redis(s.REDIS_HOST, s.REDIS_PORT, password=s.REDIS_PASSWORD, charset='utf-8')

def rebuild():
    if s.REBUILD:
        return
    s.REBUILD = True
    print("rebuild index")
    # creat redisearch index
    schema = (
        TextField("title", weight=5.0),
        TextField("content", weight=1.0),
        TagField("file_name"),
        TagField("meeting_name"),
        TagField("meeting_index")
    )

    try:
        redis_conn.ft(s.CONTENT_HASH_KEY).info()
        redis_conn.ft(s.CONTENT_HASH_KEY).dropindex(delete_documents=False)
    except redis.exceptions.ResponseError as e:
        pass

    redis_conn.ft(s.CONTENT_HASH_KEY).create_index(schema)

    cursor = "0"
    while cursor != 0:
        cursor, keys = redis_conn.scan(cursor=cursor, match=f"{s.CONTENT_HASH_KEY}:*", count=100)
        for key in keys:
            doc = redis_conn.hgetall(key)
            redis_conn.delete(key)
            redis_conn.ft(s.CONTENT_HASH_KEY).add_document(
                doc_id=key.decode(),
                language="chinese",
                title=doc.get(b'title', b'').decode(),
                content=doc.get(b'content', b'').decode(),
                file_name=doc.get(b'file_name', b'').decode(),
                meeting_name=doc.get(b'meeting_name', b'').decode(),
                meeting_index=doc.get(b'meeting_index', b'').decode()
            )

def reinit():
    # init free index list
    redis_conn.set('max_index', s.FREELIST_SIZE)
    indexes = list(range(0, s.FREELIST_SIZE))
    redis_conn.delete('free_index')
    redis_conn.lpush('free_index', *indexes)

    # delete all keys in the content hash
    cursor = "0"
    while cursor != 0:
        cursor, keys = redis_conn.scan(cursor=cursor, match=f"{s.CONTENT_HASH_KEY}:*", count=100)
        for key in keys:
            redis_conn.delete(key)

    # creat redisearch index
    schema = (
        TextField("title", weight=5.0),
        TextField("content", weight=1.0),
        TagField("file_name"),
        TagField("meeting_name"),
        TagField("meeting_index")
    )
    try:
        redis_conn.ft(s.CONTENT_HASH_KEY).info()
        redis_conn.ft(s.CONTENT_HASH_KEY).dropindex(delete_documents=True)
    except redis.exceptions.ResponseError as e:
        pass

    redis_conn.ft(s.CONTENT_HASH_KEY).create_index(schema)


def joint(lists):
    res = lists[0]
    for item in lists[1:]:
        res += ":" + str(item)
    return res


def check_free_index():
    freelist_len = redis_conn.llen('free_index')
    if freelist_len == 0:
        max_index = redis_conn.get('max_index')
        indexes = list(range(max_index, max_index + s.FREELIST_SIZE))
        redis_conn.lpush('free_index', *indexes)
        redis_conn.set('max_index', max_index + s.FREELIST_SIZE)


def delete_duplicate(meeting_name, title):
    query = Query(f'@meeting_name:{{{meeting_name}}} @file_name:{{{title}}}')
    query.language("chinese")
    query.return_field("meeting_index")
    result = redis_conn.ft(s.CONTENT_HASH_KEY).search(query).docs
    for i in range(len(result)):
        meeting_index = result[i].meeting_index
        redis_conn.lpush("free_index", meeting_index)
        redis_conn.delete(joint([s.CONTENT_HASH_KEY, meeting_index]))


def insert(folder_name):
    abs_path = redis_conn.get("folder_path").decode('utf-8')
    folder_path = os.path.join(abs_path, folder_name)
    files = os.listdir(folder_path)

    for file in files:
        if not file.endswith('.txt'):
            continue
        full_path = os.path.join(folder_path, file)
        with open(full_path, 'r', encoding='utf-8') as f:
            content = f.read()
            #content = ' '.join(jieba.cut(content))
            check_free_index()
            meeting_index = int(redis_conn.lpop("free_index"))

            title = str(file).split('.')[-2]

            delete_duplicate(folder_name, title)

            hash_key = joint([s.CONTENT_HASH_KEY, meeting_index])
            redis_conn.ft(s.CONTENT_HASH_KEY).add_document(
                doc_id=hash_key,
                language="chinese",
                title=title,
                content=content,
                file_name=title,
                meeting_name=folder_name,
                meeting_index=meeting_index
            )
    return 200


def search(keyword):
    query = Query(keyword)
    query.language("chinese")
    docs = redis_conn.ft(s.CONTENT_HASH_KEY).search(query).docs
    results = {}
    for doc in docs:
        meeting_name = doc["meeting_name"]
        file_name = doc["file_name"]
        if meeting_name not in results:
            results[meeting_name] = list()
        results[meeting_name].append(file_name)

    search_sort = []
    for meeting_name in list(results.keys()):
        search_sort.append({
            "meeting_name": meeting_name,
            "score": len(results[meeting_name]),
            "files": results[meeting_name]
        })
    search_sort.sort(key=lambda x: x["score"], reverse=True)
    return search_sort


def bring_window_to_front(window_title=None):
    if window_title:
        hwnd = win32gui.FindWindow(None, window_title)
        if hwnd:
            # 将窗口最小化，然后再最大化，以尝试将其置于最前面
            win32gui.ShowWindow(hwnd, win32con.SW_MINIMIZE)
            time.sleep(0.1)  # 等待一段时间，让操作系统有足够的时间处理窗口的最小化
            win32gui.ShowWindow(hwnd, win32con.SW_RESTORE)


def open_folder(folder_name):
    abs_path = redis_conn.get("folder_path").decode('utf-8')
    folder_path = os.path.join(abs_path, folder_name)
    os.startfile(folder_path)
    time.sleep(1)
    bring_window_to_front(window_title=folder_name)


def gen_pages(page, total_page, show_pages):
    pages = list()
    if page <= show_pages:
        start_page = 1
    else:
        start_page = page - (show_pages / 2)

    for i in range(show_pages):
        show_page = start_page + i
        if show_page > total_page:
            break
        pages.append(show_page)

    return pages


def set_folder_path(folder_path):
    if not os.path.exists(folder_path):
        return False
    else:
        redis_conn.set("folder_path", folder_path)
        return True